package com.netty.rpc.protocol;

import com.netty.rpc.config.Config;
import com.netty.rpc.message.Message;
import com.netty.rpc.serializer.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
@ChannelHandler.Sharable
public class MessageCodecSharable extends MessageToMessageCodec<ByteBuf, Message> {
    // 自定义魔数 4 字节
    private static final byte[] MAGIC_BUMBER=new byte[]{'X','U','N','M'};

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Message message, List<Object> list) throws Exception {
        // 将消息传递给外界，需要将内部消息编码
        ByteBuf byteBuf = channelHandlerContext.alloc().buffer();
        // 1. 4字节魔数
        byteBuf.writeBytes(MAGIC_BUMBER);
        // 2. 协议版本号，1字节
        byteBuf.writeByte(1);
        // 3. 序列化算法 ，1字节
        byteBuf.writeByte(Config.getSerializerAlgorithm().ordinal());// 0代表用jdk进行序列化 1代表用JSON序列化
        // 4. 指令类型，1字节
        byteBuf.writeByte(message.getMessageType());
        // 5. 请求序号，4字节
        byteBuf.writeInt(message.getSequenceId());
        // 6. 无意义,对齐填充,1字节
        byteBuf.writeByte(0xff);
        // 7. 获取内容的字节数
        Serializer.Algorithm algorithm = Config.getSerializerAlgorithm();
        byte[] content = algorithm.enserialize(message);
        // 8. 数据长度，4字节
        byteBuf.writeInt(content.length);
        // 9. 数据内容
        byteBuf.writeBytes(content);
        list.add(byteBuf);
    }

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        // 将消息传递给外界，需要将内部消息编码
        // 1. 4字节魔数
        int magicNum = byteBuf.readInt();
        // 2. 协议版本号，1字节
        byte version=byteBuf.readByte();
        // 3. 序列化算法 ，1字节
        byte serializerAlogrithm=byteBuf.readByte();
        // 4. 指令类型，1字节
        byte messageType=byteBuf.readByte();
        // 5. 请求序号，4字节
        int sequenceId = byteBuf.readInt();
        // 6. 无意义,对齐填充,1字节
        byteBuf.readByte();
        // 8. 数据长度，4字节
        int length = byteBuf.readInt();
        // 9. 数据内容
        byte[] content=new byte[length];
        byteBuf.readBytes(content);
         // 进行转化成对象
        Serializer.Algorithm algorithm = Serializer.Algorithm.values()[serializerAlogrithm];
        Object obj = algorithm.deserialize(Message.getMessageClass(messageType), content);
//        log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
//        log.debug("{}", message);
        list.add(obj);
    }
}
